﻿using EquipmentAlarmSystem.Service.Models;
using NModbus;
using System.Net.Sockets;

namespace EquipmentAlarmSystem.Service.EquipmentCommunicationUnit.Modbus;

public class Tcp(DeviceInformationModusTcp modusTcp) : ICommunication
{
    private IModbusMaster master;

    public bool Connected
    {
        get
        {
            if (master is null)
            {
                return false;
            }
            return true;

        }
    }

    public DeviceInformation Information => modusTcp;

    public bool AlarmReading(out List<PointInformation> result, out bool isReconnection, out string content)
    {
        try
        {
            result = new();
            //检查连接
            if (Connected)
            {
                Read(out List<PointInformation> value);

                foreach (var item in value)
                {
                    if (item.Value == true)
                    {
                        result.Add(item);
                    }
                }
                if (result.Count <= 0)
                {
                    result = null;
                }

                isReconnection = false;
                content = "成功";
                return true;
            }
            else
            {
                isReconnection = true;
                content = "设备未连接";
                return false;
            }
        }
        catch (Exception ex)
        {
            result = null;
            isReconnection = false;
            content = ex.Message;
            return false;
        }
    }

    public void Close()
    {
        if (master is not null)
        {
            master.Dispose();
        }
        master = null;
    }

    public void Open()
    {
        try
        {
            TcpClient client = new TcpClient(modusTcp.Ip, modusTcp.Port);

            var factory = new ModbusFactory();

            master = factory.CreateMaster(client);
        }
        catch (Exception ex)
        {
            master = null;
            throw new Exception(ex.Message);
        }
    }

    public void Read(out List<PointInformation> result)
    {
        try
        {
            //获取数据地址
            List<bool> res = new List<bool>();

            if (modusTcp.FunctionCode == FunctionBlock.Coils)
            {
                //0123456
                res = master.ReadCoils(modusTcp.SlaveAddress, (ushort)(modusTcp.StartAddress), modusTcp.NumberOfPoints).ToList();
                for (int i = 0; i < res.Count; i++)
                {
                    modusTcp.PointInformation[i].Value = res[i];
                }
            }
            if (modusTcp.FunctionCode == FunctionBlock.Inputs)
            {
                res = master.ReadInputs(modusTcp.SlaveAddress, (ushort)(modusTcp.StartAddress), modusTcp.NumberOfPoints).ToList();
                for (int i = 0; i < res.Count; i++)
                {
                    modusTcp.PointInformation[i].Value = res[i];
                }
            }
            result = modusTcp.PointInformation;
        }
        catch (Exception)
        {
            master = null;
            result = null;
        }
    }
}
